<html>
<head>
<link rel="shortcut icon" href="./favicon.ico">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="canonical" href="./Multiplexer_Binary_Behavioural.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="But first, some background on the problems with multiplexers...">
<title>Multiplexer Binary Behavioural</title>
</head>
<body>

<p class="inline bordered"><b><a href="./Multiplexer_Binary_Behavioural.v">Source</a></b></p>
<p class="inline bordered"><b><a href="./legal.html">License</a></b></p>
<p class="inline bordered"><b><a href="./index.html">Index</a></b></p>

<h1>A Reliable and Generic Binary Multiplexer (Behavioural Implementation)</h1>
<p>But first, some background on the problems with multiplexers...</p>
<h2>Simulation and Synthesis Mismatch</h2>
<p>A pitfall in the Verilog language is the treatment of unknown X values in
 <code>if</code> statements, and it can cause a mismatch between the simulated and the
 synthesized behaviours. I have observed this exact mismatch in the field.
 This problem carries over into the design of multiplexers in general.
 Here's a contrived example, where we select one of two possibilities:</p>
<pre><code> reg                         selector;
 reg     [WORD_WIDTH-1:0]    option_A;
 reg     [WORD_WIDTH-1:0]    option_B;
 reg     [WORD_WIDTH-1:0]    result;

 always @(*) begin
     if (selector == 1'b0) begin
         result = option_A;
     end
     else begin
         result = option_B;
     end
 end
</code></pre>
<p>The problem here happens if <code>selector</code> is X or Z-valued. In real hardware,
 we would expect an X or Z <code>selector</code> to cause <code>result</code> to obtain an
 X value, <em>but the <code>if</code> statement treats X as false, and so falls through to
 the <code>else</code> case</em>. The simulation returns <code>option_B</code> while the synthesis
 returns <code>X</code>. This difference can also confuse verification efforts, because
 it can show a failure in simulation where there isn't one.</p>
<p>Instead of <code>if</code> statements, we can use the ternary <code>?:</code> operator, which
 behaves as expected. Except in cases where both <code>option_A/option_B</code>
 evaluate to 1 or 0, an X or Z-valued <code>selector</code> will return an X value:</p>
<pre><code> always @(*) begin
     result = (selector == 1'b0) ? option_A : option_B;
 end
</code></pre>
<h2>Inflexible Implementations</h2>
<p>However, <a href="./verilog.html#ternary">the ternary operator gets impractical for more that two
 options</a>, and the <code>case</code> statement gets tedious and
 error-prone as the number of cases increases. And both are too rigid,
 requiring changes to the multiplexer implementation should the number of
 inputs change.</p>
<h2>A Generic Solution</h2>
<p>Instead of implementing multiple multiplexers of specific sizes, we can
 replace them all with a single multiplexer module, implemented using
 a vector part select, which simulates and synthesizes correctly, and
 accepts a parameterized number of inputs.  In the following code, we can
 think of <code>selector</code> as "addressing" one of the <code>words_in</code> options.</p>
<p>Rather than change the number of input ports at each design change, pass
 a concatenation of words to <code>words_in</code> with the zeroth element on the
 right. The <code>selector</code> then selects one of the input words. If the
 <code>selector</code> value is greater than the number of input words, the output is
 unknown (depends on synthesized logic). If the <code>selector</code> is X or Z, the
 output is X or Z.</p>
<p>This multiplexer can also cleanly express little bits of arbitrary logic:
 set the inputs to the possible output values (constant or otherwise) of
 your function, and let the <code>selector</code> input get decoded to one of those
 values.</p>

<pre>
`default_nettype none

module <a href="./Multiplexer_Binary_Behavioural.html">Multiplexer_Binary_Behavioural</a>
#(
    parameter       WORD_WIDTH          = 0,
    parameter       ADDR_WIDTH          = 0,
    parameter       INPUT_COUNT         = 0,

    // Do not set at instantiation
    parameter   TOTAL_WIDTH = WORD_WIDTH * INPUT_COUNT
)
(
    input   wire    [ADDR_WIDTH-1:0]    selector,
    input   wire    [TOTAL_WIDTH-1:0]   words_in,
    output  reg     [WORD_WIDTH-1:0]    word_out
);

    initial begin
        word_out = {WORD_WIDTH{1'b0}};
    end

    always @(*) begin
        word_out = words_in[(selector * WORD_WIDTH) +: WORD_WIDTH];
    end

endmodule
</pre>

<h2>Portability</h2>
<p>There's one problem here: if your HDL of choice does not have an analog of
 Verilog's vector part select, this design can't be translated. Thus, there
 exists <a href="./Multiplexer_Binary_Structural.html">another, more structural implementation, which can be ported to
 other HDLs</a>, and also expands the output
 function beyond the implicit Boolean OR found here.</p>

<hr>
<p><a href="./index.html">Back to FPGA Design Elements</a>
<center><a href="https://fpgacpu.ca/">fpgacpu.ca</a></center>
</body>
</html>

